import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';

import 'rxjs/add/operator/toPromise';
//Angular 的http.get返回一个 RxJS 的Observable对象。 Observable（可观察对象）是一个管理异步数据流的强力方式

import { Hero } from './hero';
import { HEROES } from './mock-heroes';

// 当 TypeScript 看到@Injectable()装饰器时，就会记下本服务的元数据。
@Injectable()                // 如果 Angular 需要往这个服务中注入其它依赖，就会使用这些元数据
export class HeroService {
    // getHeroes(): Promise<Hero[]> {
    //     return Promise.resolve(HEROES);
    // }

    // getHero(id: number): Promise<Hero> {
    //     return this.getHeroes()
    //         .then(heroes => heroes.find(hero => hero.id === id));
    // }

    getHeroesSlowly(): Promise<Hero[]> {
        return new Promise(resolve => {
            // 模拟慢速连接
            setTimeout(() => resolve(this.getHeroes()), 2000);
        });
    }

    //HTTP方式
    private heroesUrl = 'api/heroes';  // URL to web api
    constructor(private http: Http) { }
    getHeroes(): Promise<Hero[]> {
        return this.http.get(this.heroesUrl)
            .toPromise()    //现在，我们先利用toPromise操作符把Observable直接转换成Promise对象，回到已经熟悉的地盘。
            //Http服务中的每个方法都返回一个 HTTP Response对象的Observable实例。
            //我们的HeroService中把那个Observable对象转换成了Promise（承诺），并把这个承诺返回给了调用者。 
            .then(response => response.json().data as Hero[])       //在 promise 的then()回调中，我们调用 HTTP 的Reponse对象的json方法，以提取出其中的数据。
            .catch(this.handleError);      //catch了服务器的失败信息，并把它们传给了错误处理器：
    }
    private handleError(error: any): Promise<any> {
        console.error('An error occurred', error); // for demo purposes only
        return Promise.reject(error.message || error);
    }
    getHero(id: number): Promise<Hero> {
        const url = `${this.heroesUrl}/${id}`;
        return this.http.get(url)
            .toPromise()
            .then(response => response.json().data as Hero)
            .catch(this.handleError);
    }

    private headers = new Headers({ 'Content-Type': 'application/json' });
    update(hero: Hero): Promise<Hero> {
        const url = `${this.heroesUrl}/${hero.id}`;
        return this.http
            .put(url, JSON.stringify(hero), { headers: this.headers })
            .toPromise()
            .then(() => hero)
            .catch(this.handleError);
    }

    create(name: string): Promise<Hero> {
        return this.http
            .post(this.heroesUrl, JSON.stringify({ name: name }), { headers: this.headers })
            .toPromise()
            .then(res => res.json().data as Hero)
            .catch(this.handleError);
    }
    delete(id: number): Promise<void> {
        const url = `${this.heroesUrl}/${id}`;
        return this.http.delete(url, { headers: this.headers })
            .toPromise()
            .then(() => null)
            .catch(this.handleError);
    }

    getDatas(): void {
      
    }

}